/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * PowerPointCalibrate.java
 *
 * Created on Dec 16, 2012, 6:00:43 PM
 */
package UserInterface;

import controller.ColorMeanController;
import controller.SkinBasedController;
import insurface.InteractiveSurface;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.util.Arrays;
import javax.swing.Timer;
import setting.SurfaceSettings;
import utilities.Calibrate7;
import utilities.CalibrateTouch;
import utilities.CoordinateFinder;
import utilities.PlayMusic;

/**
 *
 * @author Home
 */
public class PowerPointCalibrate extends InteractiveSurface {

    Timer timer;
    PlayMusic pm = new PlayMusic();
    private SurfaceSettings settings = new SurfaceSettings();
    private int lcam = 0;
    private int rcam = 0;
    boolean isFingerSet = true;
    Thread thread;
    Graphics2D grap;
    int srcLength;
    int srcHeight;

    /** Creates new form PowerPointCalibrate */
    public PowerPointCalibrate() {
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jButton1 = new javax.swing.JButton();
        jPanel1 = new javax.swing.JPanel();
        jButton2 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setExtendedState(MAXIMIZED_BOTH);
        setUndecorated(true);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowOpened(java.awt.event.WindowEvent evt) {
                formWindowOpened(evt);
            }
        });

        jButton1.setText("jButton1");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jPanel1.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 434, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 450, Short.MAX_VALUE)
        );

        jButton2.setText("jButton2");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jButton1)
                    .addComponent(jButton2))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jButton1)
                .addGap(18, 18, 18)
                .addComponent(jButton2)
                .addContainerGap(379, Short.MAX_VALUE))
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        timer = new Timer(100, calibratePaint);
        timer.start();
    }//GEN-LAST:event_jButton1ActionPerformed

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
        this.dispose();
    }//GEN-LAST:event_jButton2ActionPerformed

    private void formWindowOpened(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowOpened
        isFingerSet = this.getIsettings().fingerSelected;
        grap = (Graphics2D) jPanel1.getGraphics();
        if (isFingerSet) {
            control = new SkinBasedController(left_Camera, right_Camera, this);
            thread = new Thread(control);

        } else {
            control = new ColorMeanController(left_Camera, right_Camera, this);
            thread = new Thread(control);
        }

        thread.start();
        timer = new Timer(100, calibratePaint);
        timer.start();
    }//GEN-LAST:event_formWindowOpened

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {

                new PowerPointCalibrate().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JPanel jPanel1;
    // End of variables declaration//GEN-END:variables
    Action calibratePaint = new AbstractAction() {

        public void actionPerformed(ActionEvent e) {
            srcLength = CoordinateFinder.getLENGTH();
            srcHeight = CoordinateFinder.getHEIGHT();

            int valX = srcLength - getX1();
            int valY = getY1();

            calibrateEight(valX, valY);

        }
    };
    Calibrate7 cal = new Calibrate7();
    boolean isCal1, isCal2, isCal3, isCal4, isCal5, isCal6, isCal7, isCal8;
    int state;
    boolean finished1, finished2, finished3, finished4, finished5, finished6, finished7, finished8;
    int x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, x7, y7, x8, y8;
    int count = 0;
    int[] xVals = new int[30], yVals = new int[30];
    double a, b, c = 1, d, e, f, g, h, i = 1, j;//used for touchpad calibration process

    public void calibrateEight(int valX, int valY) {

        isCal1 = cal.isPoint(valX, valY, 1);
        isCal2 = cal.isPoint(valX, valY, 2);
        isCal3 = cal.isPoint(valX, valY, 3);
        isCal4 = cal.isPoint(valX, valY, 4);
        isCal5 = cal.isPoint(valX, valY, 5);
        isCal6 = cal.isPoint(valX, valY, 6);
        isCal7 = cal.isPoint(valX, valY, 7);
        isCal8 = cal.isPoint(valX, valY, 8);

        switch (state) {
            case 0:
                if (finished1 && finished2 && finished3 && finished4 && finished5 && finished6 && finished7 && finished8) {
                    state = 9;
                } else if (isCal1 && !finished1) {
                    count = 0;
                    state = 1;
                    System.out.println("State 1");
                } else if (isCal2 && !finished2) {
                    count = 0;
                    state = 2;
                    System.out.println("State 2");
                } else if (isCal3 && !finished3) {
                    count = 0;
                    state = 3;
                    System.out.println("State 3");
                } else if (isCal4 && !finished4) {
                    count = 0;
                    state = 4;
                    System.out.println("State 4");
                } else if (isCal5 && !finished5) {
                    count = 0;
                    state = 5;
                    System.out.println("State 5");
                } else if (isCal6 && !finished6) {
                    count = 0;
                    state = 6;
                    System.out.println("State 6");
                } else if (isCal7 && !finished7) {
                    count = 0;
                    state = 7;
                    System.out.println("State 7");
                } else if (isCal8 && !finished8) {
                    count = 0;
                    state = 8;
                    System.out.println("State 8");
                }
                break;
            case 1:
                if (!isCal1 && count >= 30 && !isStable(xVals, yVals)) {
                    state = 0;
                    xVals = new int[30];
                    yVals = new int[30];
                    count = 0;


                } else if (count == 30) {
                    finished1 = true;
                    //statusLabel.setText("Status: Done 1");
                    pm.playSound();
                    x1 = (int) getAverage(xVals);
                    y1 = (int) getAverage(yVals);
                    xVals = new int[30];
                    yVals = new int[30];
                    state = 0;
                    count = 0;


                } else {
                    xVals[count] = valX;
                    yVals[count] = valY;
                    count++;

                }


                break;


            case 2:
                if (!isCal2 && count >= 30 && !isStable(xVals, yVals)) {
                    state = 0;
                    xVals = new int[30];
                    yVals = new int[30];
                    count = 0;


                } else if (count == 30) {
                    finished2 = true;
                    //statusLabel.setText("Status: Done 2");
                    pm.playSound();
                    x2 = (int) getAverage(xVals);
                    y2 = (int) getAverage(yVals);
                    xVals = new int[30];
                    yVals = new int[30];
                    state = 0;
                    count = 0;


                } else {
                    xVals[count] = valX;
                    yVals[count] = valY;
                    count++;

                }


                break;


            case 3:
                if (!isCal3 && count >= 30 && !isStable(xVals, yVals)) {
                    state = 0;
                    xVals = new int[30];
                    yVals = new int[30];
                    count = 0;


                } else if (count == 30) {
                    finished3 = true;
                    //statusLabel.setText("Status: Done 3");
                    pm.playSound();
                    x3 = (int) getAverage(xVals);
                    y3 = (int) getAverage(yVals);
                    xVals = new int[30];
                    yVals = new int[30];
                    state = 0;
                    count = 0;


                } else {
                    xVals[count] = valX;
                    yVals[count] = valY;
                    count++;

                }


                break;


            case 4:
                if (!isCal4 && count >= 30 && !isStable(xVals, yVals)) {
                    state = 0;
                    xVals = new int[30];
                    yVals = new int[30];
                    count = 0;


                } else if (count == 30) {
                    finished4 = true;
                    //statusLabel.setText("Status: Done 4");
                    pm.playSound();
                    x4 = (int) getAverage(xVals);
                    y4 = (int) getAverage(yVals);
                    state = 0;
                    xVals = new int[30];
                    yVals = new int[30];
                    count = 0;


                } else {
                    xVals[count] = valX;
                    yVals[count] = valY;
                    count++;

                }


                break;


            case 5:
                if (!isCal5 && count >= 30 && !isStable(xVals, yVals)) {
                    state = 0;
                    xVals = new int[30];
                    yVals = new int[30];
                    count = 0;


                } else if (count == 30) {
                    finished5 = true;
                    //statusLabel.setText("Status: Done 5");
                    pm.playSound();
                    x5 = (int) getAverage(xVals);
                    y5 = (int) getAverage(yVals);
                    xVals = new int[30];
                    yVals = new int[30];
                    state = 0;
                    count = 0;


                } else {
                    xVals[count] = valX;
                    yVals[count] = valY;
                    count++;

                }


                break;


            case 6:
                if (!isCal6 && count >= 30 && !isStable(xVals, yVals)) {
                    state = 0;
                    xVals = new int[30];
                    yVals = new int[30];
                    count = 0;


                } else if (count == 30) {
                    finished6 = true;
                    //statusLabel.setText("Status: Done 6");
                    pm.playSound();
                    x6 = (int) getAverage(xVals);
                    y6 = (int) getAverage(yVals);
                    xVals = new int[30];
                    yVals = new int[30];
                    state = 0;
                    count = 0;


                } else {
                    xVals[count] = valX;
                    yVals[count] = valY;
                    count++;

                }


                break;


            case 7:
                if (!isCal7 && count >= 30 && !isStable(xVals, yVals)) {
                    state = 0;
                    xVals = new int[30];
                    yVals = new int[30];
                    count = 0;


                } else if (count == 30) {
                    finished7 = true;
                    //statusLabel.setText("Status: Done 7");
                    pm.playSound();
                    x7 = (int) getAverage(xVals);
                    y7 = (int) getAverage(yVals);
                    xVals = new int[30];
                    yVals = new int[30];
                    state = 0;
                    count = 0;


                } else {
                    xVals[count] = valX;
                    yVals[count] = valY;
                    count++;

                }


                break;

            case 8:
                if (!isCal8 && count >= 30 && !isStable(xVals, yVals)) {
                    state = 0;
                    xVals = new int[30];
                    yVals = new int[30];
                    count = 0;
                } else if (count == 30) {
                    finished8 = true;
                    //statusLabel.setText("Status: Done 7");
                    pm.playSound();
                    x8 = (int) getAverage(xVals);
                    y8 = (int) getAverage(yVals);
                    xVals = new int[30];
                    yVals = new int[30];
                    state = 0;
                    count = 0;
                } else {
                    xVals[count] = valX;
                    yVals[count] = valY;
                    count++;
                }
                break;
            case 9: //finished calibrating
                CalibrateTouch ct = new CalibrateTouch();


                double[] rt = ct.get10Matrix8(x1, y1, x2, y2, x3, y3, x4, y4,
                        x5, y5, x6, y6, x7, y7, x8, y8,
                        150, 300, 450, 300, 750, 300, 1050, 300,
                        150, 600, 450, 600, 750, 600, 1050, 600);

                System.out.println("100,250=" + x1 + "," + y1);
                System.out.println("400,150=" + x2 + "," + y2);
                System.out.println("700,150=" + x3 + "," + y3);
                System.out.println("1000,250=" + x4 + "," + y4);
                System.out.println("200,600=" + x5 + "," + y5);
                System.out.println("500,500=" + x6 + "," + y6);
                System.out.println("800,600=" + x7 + "," + y7);

                a = rt[0];
                b = rt[1];
                c = rt[2];
                d = rt[3];
                e = rt[4];
                f = rt[5];
                g = rt[6];
                h = rt[7];
                i = rt[8];
                j = rt[9];

                System.out.println("x=" + a + "x^2+" + b + "y^2+" + c + "x+" + d + "y+" + e);
                System.out.println("y=" + f + "x^2+" + g + "y^2+" + h + "x+" + i + "y+" + j);


                getSettings().setA(a);
                getSettings().setB(b);
                getSettings().setC(c);
                getSettings().setD(d);
                getSettings().setE(e);
                getSettings().setF(f);
                getSettings().setG(g);
                getSettings().setH(h);
                getSettings().setI(i);
                getSettings().setJ(j);

                control.setActive(false);
                PowerPointApp ppapp = new PowerPointApp();
                Toolkit toolkit = Toolkit.getDefaultToolkit();
                Dimension dim = toolkit.getScreenSize();

                int x_location = (dim.width - ppapp.getBounds().width) / 2;
                int y_location = (dim.height - ppapp.getBounds().height) / 2;
                ppapp.setLocation(x_location, y_location);
                ppapp.setVisible(true);
                ppapp.setRcam(rcam);
                ppapp.setLcam(lcam);

                ppapp.setVisible(true);
                this.setVisible(false);


                break;
        }
        this.drawTarget(300, 150, finished1, isCal1);
        this.drawTarget(300, 450, finished2, isCal2);
        this.drawTarget(300, 750, finished3, isCal3);
        this.drawTarget(300, 1050, finished4, isCal4);
        this.drawTarget(600, 150, finished5, isCal5);
        this.drawTarget(600, 450, finished6, isCal6);
        this.drawTarget(600, 750, finished7, isCal7);
        this.drawTarget(600, 1050, finished8, isCal8);
    }

    public boolean isStable(int[] arX, int[] arY) {
        Arrays.sort(arX);
        Arrays.sort(arY);
        int kot = arX[20] - arX[11];
        int uol = arY[20] - arY[11];

        if (kot > 15 || uol > 15) {
            return false;
        } else {
            return true;
        }
    }

    private double getAverage(int[] ab) {

        Arrays.sort(ab);
        double fg = 0;

        for (int jkl : ab) {
            System.out.print(jkl + " ");
        }
        System.out.println("");
        for (int hr = 11; hr <= 20; hr++) {
            fg = fg + ab[hr];
        }

        return fg / 10;
    }

    public void drawTarget(int x, int y, boolean ht, boolean ht2) {
        if (ht) {
            grap.setColor(Color.GREEN);
        } else if (ht2) {
            grap.setColor(Color.RED);
        } else {
            grap.setColor(Color.BLACK);
        }
        grap.fillOval(x, y, 10, 10);
        grap.drawOval(x - 15, y - 15, 40, 40);
        grap.drawLine(x - 15, y + 5, x + 25, y + 5);
        grap.drawLine(x + 5, y - 15, x + 5, y + 25);

        jPanel1.repaint();
    }

    /**
     * @return the settings
     */
    public SurfaceSettings getSettings() {
        return settings;
    }

    /**
     * @param settings the settings to set
     */
    public void setSettings(SurfaceSettings settings) {
        this.settings = settings;
    }

    public void setLcam(int lcam) {
        this.lcam = lcam;
    }

    public void setRcam(int rcam) {
        this.rcam = rcam;
    }
}
